#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"

SLT* CreateSListNode(SLTDataType x)
{
	SLT* newNode = (SLT*)malloc(sizeof(SLTDataType));
	if (newNode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newNode->data = x;
	newNode->next = NULL;
	return newNode;
}


void SListPrint(SLT* plist)
{
	assert(plist);
	while (plist)
	{
		printf("%d ", plist->data);
		plist = plist->next;
	}
}

void SListPushBack(SLT** plist, SLTDataType x)
{
	SLT* newNode = CreateSListNode(x);

	if (*plist == NULL)
	{
		*plist = newNode;
		(*plist)->next = NULL;
	}
	else
	{
		SLT* tail = *plist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newNode;
	}
}

void SListPushFront(SLT** plist, SLTDataType x)
{
	SLT* newNode = CreateSListNode(x);
	newNode->next = *plist;
	*plist = newNode;
}


void SListPopBack(SLT** plist)
{
	assert(*plist);

	if ((*plist)->next == NULL)
	{
		free(*plist);
		*plist = NULL;
	}
	else
	{
		SLT* tail = *plist;
		while (tail->next->next != NULL)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

void SListPopFront(SLT** plist)
{
	assert(*plist);
	SLT* tmp = *plist;
	*plist = (*plist)->next;
	free(tmp);
}

SLT* SListFind(SLT* plist, SLTDataType x)
{
	assert(plist);

	SLT* cur = plist;
	while (cur)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}

void SListInsert(SLT** pphead, SLT* pos, SLTDataType x)
{
	assert(pos);
	assert((*pphead && pos) || (!(*pphead) && !pos));

	if (*pphead == pos)
	{
		SListPushFront(pphead, x);
	}
	else
	{
		SLT* newNode = CreateSListNode(x);
		SLT* cur = *pphead;
		while (cur->next != pos)
		{
			cur = cur->next;
		}
		newNode->next = pos;
		cur->next = newNode;
	}

}

void SLTErase(SLT** pphead, SLT* pos)
{
	assert(pphead);
	assert(*pphead);
	assert(pos);

	if (*pphead == pos)
	{
		SListPopFront(pphead);
	}
	else
	{
		SLT* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;

		free(pos);
		pos = NULL;
	}
}

void SLTInsertAfter(SLT* pos, SLTDataType x)
{
	assert(pos);
	SLT* newNode = CreateSListNode(x);

	newNode->next = pos->next;
	pos->next = newNode;

}

void SLTEraseAfter(SLT* pos)
{
	assert(pos);
	assert(pos->next);

	SLT* tmp = pos->next;
	pos->next = tmp->next;
	free(tmp);
	tmp = NULL;
}

void SListDestroy(SLT** pphead)
{
	assert(pphead);
	assert(*pphead);

	SLT* tmp = *pphead;
	SLT* next = NULL;
	while (tmp != NULL)
	{
		next = tmp->next;
		free(tmp);
		tmp = next;
	}
	*pphead = NULL;
}